home *** CD-ROM | disk | FTP | other *** search
- /*******************************<+>***************************
- ** DTA
- *************************************************************
- **
- ** $Id:
- **
- ** $Source:
- **
- ** Module Name:
- **
- ** Classification: Unclassified
- **
- ** Author: Dale T. Anderson
- **
- *******************************<+>***************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #ifndef linux
- #include <malloc.h>
- #endif
- #include <assert.h>
-
- char **tokens = NULL;
-
- unsigned tcount = 0;
- unsigned tlength = 0;
-
- int debug = 0;
- int dostatic = 0;
- int dointernal = 0;
- int doverbose = 1;
- int douseproto = 1;
- int doextern = 0;
- int iscxx = 0;
- int doapi = 0;
-
- int isblankline (str)
- char *str;
- {
- while (*str && (*str == '\n' || *str == ' ' || *str == '\t'))
- str++;
- return (*str == 0);
- }
-
- int find_token (start, str)
- int start;
- char *str;
- {
- int i;
-
- for (i = start; i < tcount; i++)
- if (!strcmp (str, tokens[i]))
- return (i);
- return (-1);
- }
-
- int last_token (start, str)
- int start;
- char *str;
- {
- int i;
-
- for (i = tcount - 1; i >= start; i--)
- if (!strcmp (str, tokens[i]))
- return (i);
- return (-1);
- }
-
- void add_token ()
- {
- static int total = 0;
- int i;
-
- if (!total || tcount == total - 1) {
- total += 256;
- if (tokens)
- tokens = (char **) realloc ((char *) tokens, sizeof (char *) * total);
- else
- tokens = (char **) malloc (sizeof (char *) * total);
-
- for (i = tcount; i < total; i++)
- tokens[i] = malloc (128);
- }
- if (tlength) {
- assert (tlength < 80);
- tokens[tcount][tlength] = 0;
- if (!strcmp (tokens[tcount], "va_alist"))
- strcpy (tokens[tcount], "...");
- if (!strcmp (tokens[tcount], "va_dcl"))
- strcpy (tokens[tcount], "...");
- tlength = 0;
- tcount++;
- }
- }
-
- void token_char (ch)
- char ch;
- {
- tokens[tcount][tlength] = ch;
- tlength++;
- }
-
- void print_header (stream, name)
- FILE *stream;
- char *name;
- {
- if (!iscxx) {
- fprintf (stream, "\n/*\n");
- fprintf (stream, " * %s\n", name);
- fprintf (stream, " */\n\n");
- } else {
- fprintf (stream, "\n//\n");
- fprintf (stream, "// %s\n", name);
- fprintf (stream, "//\n\n");
- }
- }
-
- void print_fun (stream, beg, end)
- FILE *stream;
- int beg;
- int end;
- {
- int i;
-
- if (!dostatic && doextern)
- fprintf (stream, "extern ");
-
- for (i = beg; i <= end; i++) {
- if (i > beg)
- fputc (' ', stream);
- fprintf (stream, tokens[i]);
- }
-
- fprintf (stream, " (");
-
- if (douseproto)
- fprintf (stream, "\n");
- }
-
- typedef enum {True, False} Boolean;
-
- static Boolean IsLastParameter(idx, end)
- int idx;
- int end;
- {
- static Boolean in_if = False;
- static Boolean in_else = False;
-
- if (idx == end) {
- in_if = in_else = False;
- return True;
- }
- /*
- * case 1: if last token is a parameter, and not analyzing last parameter,
- * then no special cases exist
- */
- else if (tokens[end][0] != '#')
- return False;
- else if (strncmp(tokens[idx], "#if",3) == 0 ||
- strncmp(tokens[idx],"#elif",5) == 0) {
- in_if = True;
- in_else = False;
- } else if (strncmp(tokens[idx], "#else",5) == 0) {
- in_else = True;
- in_if = False;
- } else if (strncmp(tokens[idx], "#endif", 6) == 0) {
- in_else = in_if = False;
- }
- /*
- * case 2: inside an #else or #elif, and currently on next to last token. Last
- * token should be a #endif - else a syntax error will occur most likely
- * in C Compiler or preprocessor if missing the #endif
- */
- if (in_else == True && idx == (end - 1)) /*Last parameter of #else*/
- return True;
- /*
- * case 3: inside the #if..., need to find the last token in the last #if
- * clause, and if currently in that, return that this is last parameter
- */
- else if (in_if == True) {
- int i;
- for (i=idx+1; i<end; i++) {
- if (tokens[i][0] == '#') {
- if (i > (idx + 1))
- return False;
- else {
- int j;
- for (j=i; j<end; j++)
- if (strncmp(tokens[j], "#endif", 6) == 0)
- break;
- if (j == end) /*Last #endif clause - this is last parm.*/
- return True;
- }
- }
- }
- }
- return False;
- }
-
- void print_args (stream, beg, end)
- FILE *stream;
- int beg;
- int end;
- {
- int tab;
- int i;
-
- if (douseproto)
- fprintf (stream, "#ifdef UseProto\n");
- if (beg > end) {
- if (douseproto)
- fprintf (stream, "\tvoid\n");
- else
- fprintf (stream, "void");
- } else {
- tab = tokens[beg][0] == '#' ? 0 : 1;
- for (i = beg; i <= end; i++) {
- if (tab) {
- if (douseproto)
- fputc ('\t', stream);
- tab = 0;
- }
- (void) IsLastParameter(i,end);
- if (tokens[i][0] == ';' || tokens[i][0] == ',') {
- if (IsLastParameter(i, end) == False)
- fputc (',', stream);
- } else {
- if (i && tokens[i - 1][0] != '*' && tokens[i - 1][0] != '[' &&
- tokens[i][0] != '#' && i != beg)
- fputc (' ', stream);
- fprintf (stream, tokens[i]);
- }
- if (tokens[i][0] == '#' || tokens[i][0] == ',' ||
- tokens[i][0] == ';' || i == end) {
- if (douseproto)
- fputc ('\n', stream);
- if (i != end)
- tab = tokens[i+1][0] == '#' ? 0 : 1;
- }
- }
- }
- if (douseproto)
- fprintf (stream, "#endif\n");
-
- fprintf (stream, ");\n");
-
- if (doverbose)
- fprintf (stream, "\n");
- }
-
- void tokenize (ch)
- char ch;
- {
- switch (ch) {
- case ' ':
- case '\t':
- add_token ();
- break;
- case '*':
- case '[':
- case ']':
- case '(':
- case ')':
- case ',':
- case ';':
- add_token ();
- token_char (ch);
- add_token ();
- break;
- default:
- token_char (ch);
- }
- }
-
- int add_line (buf)
- char *buf;
- {
- int i;
-
- if (tcount > 0 && buf[0] == '#') {
- (void) strcpy (tokens[tcount], buf);
- tlength += strlen(buf);
- tokenize(' ');
- return 0;
- }
-
- if (!strchr(buf, '=') && !strchr(buf, '#')) {
- for (i = 0; buf[i]; i++)
- tokenize (buf[i]);
- tokenize (' ');
- }
- return 0;
- }
-
- int valid_name (name)
- char *name;
- {
- int i;
-
- if (!doapi && !strcmp (name, "..."))
- return (0);
-
- if (!doapi && strstr (name, "::"))
- return (-1);
-
- if (!strcmp (name, "main"))
- return (-1);
-
- if (!isalpha (*name) && *name != '_')
- return (-1);
-
- for (i = 1; name[i]; i++) {
- if (!(isalpha (name[i]) || isdigit (name[i]) || name[i] == '_' || name [i] == ':'))
- return (-1);
- }
-
- return (0);
- }
-
- int get_start (open_paren)
- int open_paren;
- {
- int semi;
- int start;
-
- start = 0;
-
- while ((semi = find_token (start, ";")) >= 0) {
- if (semi < open_paren)
- start = semi + 1;
- else
- break;
- }
-
- return (start);
- }
-
- int print_prototype (stream)
- FILE *stream;
- {
- int open_paren;
- int close_paren;
- int start;
- int i;
-
- if (debug && tcount) {
- printf ("<");
- for (i = 0; i < tcount; i++)
- printf ("\t%d: %s\n", i, tokens[i]);
- printf (">\n");
- }
-
- if ((close_paren = last_token (0, ")")) < 0 || close_paren < 1)
- return (-1);
-
- for (i = -1, open_paren = close_paren - 1; open_paren >= 0; open_paren--) {
- if (tokens[open_paren][0] == '(')
- i++;
- else if (tokens[open_paren][0] == ')')
- i--;
- if (!i)
- break;
- }
-
- if (i)
- return (-2);
-
- for (start = open_paren; start > 0; start--)
- if (!strcmp (tokens [start], ";"))
- break;
-
- for (i = start; i < open_paren; i++) {
- if (tokens[i][1] && valid_name (tokens[i]) < 0)
- return (-100 - i);
- }
-
- /*
- * check for token streams that should be thrown away
- */
-
- if (!dointernal && (tokens[open_paren - 1][0] == '_'))
- return (-3);
-
- if ((start = get_start (open_paren)) < 0)
- return (-4);
-
- if (!strcmp (tokens[start], "extern"))
- return (-5);
-
- if (!strcmp (tokens[start], "typedef"))
- return (-5);
-
- if (!dostatic == (!strcmp (tokens[start], "static")))
- return (-6);
-
- /*
- * function has no return type, so too bad!
- */
-
- while (tcount > 0 && !strcmp (tokens [tcount - 1], "const"))
- tcount--;
-
- if (open_paren - start <= 1)
- return (-7);
-
- /*
- * print the function name and return type
- */
-
- print_fun (stream, start, open_paren - 1);
-
- /*
- * look for the colon following constructors, ignore after
- */
-
- if (!strcmp (tokens [close_paren + 1], ":"))
- tcount = close_paren + 1;
-
- /*
- * check for inline prototypes or K & R prototypes
- */
-
- if (close_paren == tcount - 1)
- print_args (stream, open_paren + 1, close_paren - 1);
- else
- print_args (stream, close_paren + 1, tcount - 1);
-
- return (0);
- }
-
- #define isfluff(c) (c == '\n' || c == ' ' || c == '\t')
-
- void runfile (stream, out_fp)
- FILE *stream;
- FILE *out_fp;
- {
- char buffer[1024];
- char newbuf[1024];
- int infunction;
- int incomment;
- int inmacro;
- int len;
- int i;
- int j;
- int ret;
- char *p;
-
- infunction = 0;
- incomment = 0;
- inmacro = 0;
-
- while (fgets (buffer, sizeof (buffer), stream)) {
- len = strlen (buffer);
-
- while (len > 0 && isfluff (buffer [len - 1]))
- buffer [--len] = 0;
-
- inmacro = 0;
-
- if ((p = strstr (buffer, "//")))
- *p = 0;
-
- if (*buffer == '#' && strstr (buffer, "define")) {
- if (strstr (buffer, "NOFANSI"))
- return;
-
- inmacro = 1;
- if (debug)
- printf ("Skip %s\n", buffer);
- while (buffer [len - 1] == '\\'
- && fgets (buffer, sizeof (buffer), stream)) {
- len = strlen (buffer);
- while (isfluff (buffer [len - 1]))
- buffer [--len] = 0;
-
- if (debug)
- printf ("Skip %s\n", buffer);
- }
- }
-
- if (inmacro)
- continue;
-
- for (j = i = 0; buffer[i]; i++) {
- if (!incomment && buffer[i] == '{') {
- if (!infunction) {
- if ((ret = print_prototype (out_fp)) < 0 && debug)
- printf ("Error %d\n", ret);
- tcount = 0;
- }
- infunction++;
- } else if (!incomment && buffer[i] == '}') {
- infunction--;
- } else {
- if (buffer[i] == '/') {
- if (incomment && i && buffer[i - 1] == '*')
- incomment--;
- else if (buffer[i + 1] == '*')
- incomment++;
- } else {
- if (!infunction && !incomment)
- newbuf[j++] = buffer[i];
- }
- }
- }
- /*printf ("buff = %s %d %d\n", buffer, infunction, incomment);*/
- if (j) {
- newbuf[j] = 0;
- if (debug)
- printf ("Add line %s\n", newbuf);
- if (add_line (newbuf) < 0)
- return;
- }
- }
- if ((ret = print_prototype (out_fp)) < 0 && debug)
- printf ("Error %d\n", ret);
- tcount = 0;
- }
-
- int main (argc, argv)
- int argc;
- char **argv;
- {
- extern int optopt;
- FILE *stream;
- int errflg = 0;
- int c;
-
- while ((c = getopt (argc, argv, "adesipv")) != -1) {
- switch (c) {
- case 'a':
- doextern = 0;
- douseproto = 0;
- doverbose = 0;
- doapi = 1;
- break;
- case 'd':
- debug = 1;
- break;
- case 'e':
- doextern = 1;
- break;
- case 's':
- dostatic = 1;
- break;
- case 'i':
- dointernal = 1;
- break;
- case 'p':
- douseproto = 0;
- break;
- case 'v':
- doverbose = 0;
- break;
- case ':':
- fprintf(stderr, "Option -%c requires an argument\n", optopt);
- errflg++;
- break;
- case '?':
- fprintf(stderr, "Unrecognized option: - %c\n", optopt);
- errflg++;
- break;
- }
- }
-
- add_token ();
-
- while (optind < argc) {
- if (argv [optind][strlen (argv[optind]) - 1] == 'C') {
- iscxx = 1;
- douseproto = 0;
- } else if (strstr (argv [optind], ".cc")) {
- iscxx = 1;
- douseproto = 0;
- }
-
- if ((stream = fopen (argv [optind], "r"))) {
- if (doverbose)
- print_header (stdout, argv [optind]);
- runfile (stream, stdout);
- fclose (stream);
- } else
- perror (argv [optind]);
-
- optind++;
- }
-
- return (0);
- }
-